package com.dx.mes.service.warehouse.service;

import com.dx.common.table.ppt.*;
import com.dx.mes.common.bean.erp.EWOWHIN;
import com.dx.mes.common.core.rabbitmq.BaseConnFactory;
import com.dx.mes.common.dao.*;
import com.dx.mes.common.transcoder.util.*;
import com.dx.mes.facade.warehouse.service.IFwpwmsopeService;
import com.dx.mes.facade.warehouse.tx.Fwpwmsope.FwpwmsopeI;
import com.dx.mes.facade.warehouse.tx.Fwpwmsope.FwpwmsopeIA;
import com.dx.mes.facade.warehouse.tx.Fwpwmsope.FwpwmsopeO;
import com.dx.mes.facade.warehouse.tx.Fwpwmsope.FwpwmsopeOA;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.dx.mes.common.bean.def.GenericDef.*;

@Service("fwpwmsopeService")
@SuppressWarnings({"unchecked"})
public class FwpwmsopeService implements IFwpwmsopeService {
    private static final String TX_NAME = T_FWPWMSOPE;
    private LogUtils logUtils;

    @Autowired
    private IRetWODao retWODao;
    @Autowired
    private IRetBoxDao retBoxDao;
    @Autowired
    private IRetPrdInfoDao retPrdInfoDao;
    @Autowired
    private IBisDataDao bisDataDao;
    @Autowired
    private IRetCrtNoDao retCrtNoDao;
    @Autowired
    private IRetBoxShtcDao retBoxShtcDao;
    @Autowired
    private IRetPrdInfoShtcDao retPrdInfoShtcDao;
    @Autowired
    private IRetShipNoticeDao retShipNoticeDao;
    @Autowired
    private IBisMdlDefDao bisMdlDefDao;
    @Autowired
    private IRetPalletDao retPalletDao;
    @Resource
    private BaseConnFactory baseConnFactory;

    @Override
    public String subMainProc(String evt_no, String strInTrx) {
        AppContext.clear();
        AppContext.setCurrServiceName(FwpwmsopeService.class.getSimpleName());
        AppContext.setCurrEventNumber(evt_no);
        logUtils = new LogUtils(FwpwmsopeService.class);
        logUtils.info("[InTrx:" + strInTrx + "]");

        Session session = retWODao.getCrSession();
        FwpwmsopeO outTrx = new FwpwmsopeO();
        String strOutTrx = null;

        outTrx.setTrx_id(TX_NAME);
        outTrx.setType_id(TRX_OUT);
        outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));

        // 输入对象
        try {
            FwpwmsopeI inTrx = new FwpwmsopeI();
            // 将json字符串转换成对象
            inTrx = JacksonUtil.fromJson(strInTrx, FwpwmsopeI.class);
            char action_flg = inTrx.getAction_flg().charAt(0);

            switch (action_flg) {
                case 'Q':
                    queryByCondition(inTrx, outTrx);
                    break;
                case 'I':
                    whInFnc(inTrx, outTrx);//入库
                    break;
                default:
                    errActionFnc(outTrx);
            }
            if (RETURN_CODE_OK.equals(outTrx.getRtn_code())) {
                session.flush();
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        } catch (Exception ex) {
            outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
            outTrx.setRtn_mesg(ex.toString());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        } finally {
            // 将一个 Object 或者List对象转化为JSOObject或者JSONArray
        }
        strOutTrx = JacksonUtil.toJSONStr(outTrx);
        logUtils.info("[OutTrx:" + strOutTrx + "]");
        return strOutTrx;
    }

    public void queryByCondition(FwpwmsopeI inTrx, FwpwmsopeO outTrx) {
        FwpwmsopeIA iary = inTrx.getIary().get(0);
        String boxId = iary.getBox_id();
        String woId = iary.getWo_id();

        // Session session = retBoxDao.getCrSession();
        String hql = "From Ret_box where 1 = 1 ";
        if (null != boxId && boxId.length() != 0) {
            hql = hql + "and box_id = '" + boxId + "'";
        }
        if (null != woId && woId.length() != 0) {
            hql = hql + " and wo_id_fk = '" + woId + "'";
        }
        hql = hql + " and (box_stat = 'COMP' or box_stat = 'SHIP')";
        hql += " and box_cate =  'W' ";

        List<Ret_box> ret_boxs = retBoxDao.find(hql);

        List<FwpwmsopeOA> oary = new ArrayList<FwpwmsopeOA>();
        for (Ret_box ret_box : ret_boxs) {
            FwpwmsopeOA fwpwmsopeOA = new FwpwmsopeOA();
            String woIdFk = ret_box.getWo_id_fk();
            String mdlIdFk = ret_box.getMdl_id_fk();
            String batchNoFk = ret_box.getBatch_no_fk();
            Integer prdQty = ret_box.getPrd_qty();
            String boxid = ret_box.getBox_id();
            String boxStat = ret_box.getBox_stat();
            Timestamp whInTimeStamp = ret_box.getWh_in_timestamp();
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 定义格式，不显示毫秒
            String whInTimestamp = "";
            if (whInTimeStamp != null) {
                whInTimestamp = df.format(whInTimeStamp);
            }
            fwpwmsopeOA.setBox_id(boxid);
            fwpwmsopeOA.setWo_id(woIdFk);
            fwpwmsopeOA.setMdl_id_fk(mdlIdFk);
            fwpwmsopeOA.setBatch_no_fk(batchNoFk);
            fwpwmsopeOA.setPrd_qty(prdQty);
            fwpwmsopeOA.setBox_stat(boxStat);
            fwpwmsopeOA.setWh_in_timestamp(whInTimestamp);
            //判断箱子当前入库状态
            if(PROC_COMPLETE.equals(boxStat) && Util.isSpaceCheck(ret_box.getBnk_flg())){
                fwpwmsopeOA.setWh_stat("等待申请");
            }
            if(PROC_SHIP.equals(boxStat) && BANK_IN.equals(ret_box.getBnk_flg())){
                fwpwmsopeOA.setWh_stat("已经申请");
            }
            if(PROC_SHIP.equals(boxStat) && BANK_COMP.equals(ret_box.getBnk_flg())){
                fwpwmsopeOA.setWh_stat("入库完成");
            }
            Ret_wo ret_wo = retWODao.get(woIdFk);
            if(ret_wo !=null){
                String cusIdFk = ret_wo.getCus_id_fk();
                fwpwmsopeOA.setCus_id_fk(cusIdFk);
            }
            oary.add(fwpwmsopeOA);
        }
        outTrx.setOary(oary);
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }

    // 入库
    public void whInFnc(FwpwmsopeI inTrx, FwpwmsopeO outTrx) {
        List<FwpwmsopeIA> iarys = inTrx.getIary();
        String evtUsr =inTrx.getEvt_user();
        String relateUsr = inTrx.getRelate_usr();
        String destShop = inTrx.getDest_shop();
//        String storageLoc = inTrx.getStorage_loc();
        Timestamp gEvtTimestamp = Util.getCurrentTimestamp();
        String evtTimeforVer  = Util.getEvtTimeforVer();

        // 1.检查仓位
        String hql3 = "FROM Bis_data where data_cate = 'DEST' and data_ext = '" + destShop + "'";
        List<Bis_data> shopList = new ArrayList<Bis_data>();
        shopList = bisDataDao.find(hql3);
        if (shopList.isEmpty()) {
            outTrx.setRtn_code(E_READ_NOT_FOUND + "");
            outTrx.setRtn_mesg("仓别[" + inTrx.getDest_shop() + "]不存在！");
            return;
        }

        // 2.检查箱子
        if(iarys.isEmpty()){
            outTrx.setRtn_code(E_READ_NOT_FOUND + "");
            outTrx.setRtn_mesg("请选择需要入库的箱子");
            return;
        }
        List<Ret_box> ret_boxes = new ArrayList<Ret_box>();
        List<Ret_box> ret_boxNs = new ArrayList<>();
        List<Trans_prd_in> trans_prd_ins = new ArrayList<>();
        List<Trans_prd_indt> trans_prd_indts = new ArrayList<>();
        Integer prdQtys = 0;
        List<EWOWHIN> ewowhinList = new ArrayList<EWOWHIN>();
        for (FwpwmsopeIA iary : iarys) {
            String  mesRsvNo = "W"+ GUIDGenerator.javaGUID().substring(0,11);
            Ret_wo ret_wo = new Ret_wo();
            ret_wo = retWODao.getWithLock(iary.getWo_id(), LockMode.UPGRADE);
            if (null == ret_wo) {
                outTrx.setRtn_code(E_RET_WO + E_READ_NOT_FOUND + "");
                outTrx.setRtn_mesg("工单号[" + iary.getWo_id() + "]不存在！");
                return;
            }
            // Get box
            Ret_box box = new Ret_box();
            box = retBoxDao.getWithLock(iary.getBox_id(), LockMode.UPGRADE);
            if (null == box) {
                outTrx.setRtn_code(E_RET_BOX + E_READ_NOT_FOUND + "");
                outTrx.setRtn_mesg("箱子[" + iary.getBox_id() + "]不存在！");
                return;
            }

            if (!ret_wo.getWo_id().equals(box.getWo_id_fk())) {
                outTrx.setRtn_code(E_FWPWMSOPE_WO_UNMATCH + "");
                outTrx.setRtn_mesg("箱子 [" + iary.getBox_id() + "] 工单号为[" + box.getWo_id_fk() + "]，不属于工单["
                        + ret_wo.getWo_id() + "]");
                return;
            }

            // Check box info
            if (!PROC_COMPLETE.equals(box.getBox_stat())) {
                outTrx.setRtn_code(INVALIED_BOX_STAT + "");
                outTrx.setRtn_mesg("入库的箱子状态必须是 " + PROC_COMPLETE + ", [" + box.getBox_id() + "] 当前状态是 ["
                        + box.getBox_stat() + "]");
                return;
            }
            if(BANK_IN.equals(box.getBnk_flg())){
                outTrx.setRtn_code(INVALIED_BOX_STAT + "");
                outTrx.setRtn_mesg("[" + box.getBox_id() + "] 箱子已经是入库申请状态了");
                return;
            }

            // Fetch panels 抽片检查
            List<Ret_prd_info> prdInfoList = new ArrayList<Ret_prd_info>();
           /* prdInfoList = retPrdInfoDao.getShtListInfo(iary.getBox_id());*/
            String hql1 = "From Ret_box where ship_box_id= '"+iary.getBox_id()+"'";
            List<Ret_box> retBoxList = retBoxDao.find(hql1);//内箱
            for(int i = 0; i < retBoxList.size(); i++){
                String boxId = retBoxList.get(i).getBox_id();
                List<Ret_prd_info> infoList = retPrdInfoDao.getShtListInfo(boxId);
                if(infoList!=null && infoList.size()>0){
                    prdInfoList.addAll(infoList);
                }
            }

            if (null != prdInfoList) {
                if (Long.valueOf(iary.getPrd_qty()) == prdInfoList.size() && prdInfoList.size() == box.getPrd_qty()) {
                    if (!PROC_COMPLETE.equals(prdInfoList.get(0).getPrd_stat())) {
                        outTrx.setRtn_code(INVALIED_SHT_STAT + "");
                        outTrx.setRtn_mesg(
                                "成品入库的玻璃状态必须为 " + PROC_COMPLETE + ", [" + prdInfoList.get(0).getPrd_seq_id()
                                        + "] 当前状态是 [" + prdInfoList.get(0).getPrd_stat() + "]");
                        return;
                    }
                    for (Ret_prd_info item : prdInfoList) {
                        item.setPv_prd_stat_fk(item.getPrd_stat());
                        item.setPrd_stat(PROC_SHIP);
                        item.setRsv_no(mesRsvNo);
                        item.setEvt_cate(EVT_WHIN);
                        //item.setBnk_flg(DEST_SHOP_BANK_FLG_NO_WIP);
                        item.setDest_shop(inTrx.getDest_shop());
                        item.setBnk_flg(BANK_IN);
//                        item.setStorage_loc(inTrx.getStorage_loc());
                        item.setEvt_usr(inTrx.getEvt_user());
                        item.setRelate_usr(inTrx.getRelate_usr());
                        item.setEvt_timestamp(gEvtTimestamp);
                        item.setWh_in_timestamp(gEvtTimestamp);
                        retPrdInfoDao.update(item);
                    }
                } else {
                    outTrx.setRtn_code(INVALIED_SHT_CNT + "");
                    outTrx.setRtn_mesg("Box [" + iary.getBox_id() + "] has [" + iary.getPrd_qty()
                            + "] panels, but only find [" + prdInfoList.size() + "].");
                    return;
                }
            } else {
                outTrx.setRtn_code(E_FWPWMSOPE_FIND_NO_PANEL_BY_BOX + "");
                outTrx.setRtn_mesg("No panel in box [" + iary.getBox_id() + "].");
                return;
            }


 /*         // 更新ret_wo   入库后更新
            ret_wo.setEvt_timestamp(gEvtTimestamp);
            ret_wo.setEvt_usr(inTrx.getEvt_user());
            ret_wo.setWh_in_prd_qty(ret_wo.getWh_in_prd_qty() + box.getPrd_qty());
            if (ret_wo.getWh_in_prd_qty().intValue() + ret_wo.getScrp_prd_qty().intValue() > ret_wo.getRl_prd_qty()
                    .intValue()) {
                outTrx.setRtn_code(E_FWPWMSOPE_WO_CNT_NOT_ENOUGH + "");
                outTrx.setRtn_mesg("工单 [" + iary.getWo_id() + "] 释放数量 [" + ret_wo.getRl_prd_qty() + "],报废数量["
                        + ret_wo.getScrp_prd_qty() + "] + 入库数量 [" + ret_wo.getWh_in_prd_qty() + "] 汇总超标！!");
                return;
            }

            if (ret_wo.getComp_prd_qty().intValue() < 0) {
                outTrx.setRtn_code(E_FWPWMSOPE_WO_CNT_NOT_ENOUGH + "");
                outTrx.setRtn_mesg("工单 [" + iary.getWo_id() + "] 完成数量 [" + ret_wo.getComp_prd_qty() + "] 小于箱子数量 ["
                        + box.getPrd_qty() + "] !");
                return;
            }
            retWODao.update2(ret_wo);
*/
            //更新箱子状态  外箱
            String boxId = iary.getBox_id();
            Ret_box ret_box = retBoxDao.get(boxId);
            ret_box.setBox_stat(PROC_SHIP);
            ret_box.setRelate_usr(relateUsr);
            ret_box.setDest_shop(destShop);
            ret_box.setBnk_flg(BANK_IN);
//            ret_box.setStorage_loc(storageLoc);
            ret_box.setWh_in_timestamp(gEvtTimestamp);
            ret_box.setEvt_timestamp(gEvtTimestamp);
            ret_box.setEvt_usr(evtUsr);
            ret_box.setEvt_cate(EVT_WHIN);
            ret_box.setBnk_flg(DEST_SHOP_BANK_FLG_NO_WIP);
            ret_boxes.add(ret_box);

            //更新内箱状态
            for(int i=0; i < retBoxList.size(); i++){
                Ret_box ret_boxN = retBoxList.get(i);
                ret_boxN.setBox_stat(PROC_SHIP);
                ret_boxN.setRelate_usr(relateUsr);
                ret_boxN.setBnk_flg(BANK_IN);
                ret_boxN.setDest_shop(destShop);
                ret_boxN.setWh_in_timestamp(gEvtTimestamp);
                ret_boxN.setEvt_timestamp(gEvtTimestamp);
                ret_boxN.setEvt_usr(evtUsr);
                ret_boxN.setEvt_cate(EVT_WHIN);
                ret_boxN.setBnk_flg(DEST_SHOP_BANK_FLG_NO_WIP);
                ret_boxNs.add(ret_boxN);
            }
            //入库后信息发给SAP
            EWOWHIN ewowhin = new EWOWHIN();
            ewowhin.setAUFNR(ret_wo.getWo_id());
            ewowhin.setAUART(ret_wo.getWo_cate());
            ewowhin.setWEMPF(mesRsvNo);
            ewowhin.setMATNR(ret_wo.getMdl_id_fk());
            ewowhin.setMENGE(box.getPrd_qty());
            ewowhin.setMEINS("PCS");
            ewowhin.setCHARG("W"+ret_wo.getWo_id());
            ewowhin.setZBWART("Z05");
            ewowhin.setBWART("101");
            ewowhin.setWERKS(ret_wo.getFab_id_fk());//工厂
            String hqlA ="FROM Bis_data where data_cate ='DEST' and data_ext ='" + destShop + "'";
            List<Bis_data> destList = bisDataDao.find(hqlA);
            if(destList!=null && destList.size()>0){
                ewowhin.setLGORT(destList.get(0).getExt_2());//接受仓位
            }
            ewowhin.setUMLGO(destShop);//发出库存地址
            Format dateFormat = new SimpleDateFormat("yyyyMMdd");
            String date  = dateFormat.format(new Date());
            ewowhin.setHSDAT(date);
            ewowhin.setBUDAT(date);
            ewowhinList.add(ewowhin);
        }
//        try {
//            baseConnFactory.addSAPREQProc("EWOWHIN", JacksonUtil.toJSONStr(ewowhinList));
//        }catch (Exception e){
//            e.printStackTrace();
//        }
        // 更新box_stat状态
        retBoxDao.saveOrUpdateAll(ret_boxes);//外箱
        retBoxDao.saveOrUpdateAll(ret_boxNs);//内箱


        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }

    // 错误信息
    public void errActionFnc(FwpwmsopeO outTrx) {
        outTrx.setRtn_code("0000009");
        outTrx.setRtn_mesg("Invalid Action_flg");
    }

}